﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using _404park.ApplicationServices.Content;
using _404park.ApplicationServices.Crawler;
using _404park.Utilities;
using _404park.Utilities.Web;
using _404park.Web.Models;
using _404park.ApplicationServices;
using _404park.ApplicationServices.SearchProvider;
using _404park.ApplicationServices.Crawler.Parser;

namespace _404park.Web.Controllers
{
    public class HomeController : Controller
    {
        private readonly string _resultUrl = ConfigurationManager.AppSettings["googleSearchResultUrl"];
        private readonly string _hostName = ConfigurationManager.AppSettings["hostName"];
        private readonly int _relatedKeywordsLimit = ConfigurationManager.AppSettings["relatedKeywordsLimit"] == null ?
            10 : int.Parse(ConfigurationManager.AppSettings["relatedKeywordsLimit"]);
        private readonly IKeywordService _keywordService = new KeywordService();

        #region Action

        public ActionResult Index()
        {
            try
            {
                var keywords = _keywordService.BuildKeywords(Request.Url.Host);
                if (string.IsNullOrEmpty(keywords))
                    keywords = AppGlobal.DefaultKeywords;

                ISearchProvider searchProvider = null;

                //if (Request.Browser.IsMobileDevice)
                //    searchProvider = SearchProviderManager.GetSearchProvider("Google");
                //else
                //    searchProvider = SearchProviderManager.PlayDice();

                searchProvider = SearchProviderManager.GetSearchProvider("Yahoo");

                if (!Request.Url.ToString().Contains(AppGlobal.AppHost))
                {
                    var redirectUrl = string.Concat(searchProvider.BuildNavigateUrl(keywords), "&originalurl=", Request.Url.Host, "&sp=", searchProvider.Name);
                    return new RedirectResult(redirectUrl);
                }

                EnsureItems(string.Empty, searchProvider);

                ViewBag.TopKeywords = GetTopKeywords(searchProvider);
                ViewBag.TopTags = GetTopTags(searchProvider);

            }
            catch (Exception ex)
            {
            }

            return View();
        }

        public ActionResult GResult()
        {
            var keywords = Request.QueryString["q"] ?? string.Empty;
            var originalUrl = Request.QueryString["originalurl"] ?? string.Empty;

            ViewBag.SearchProvider = "G";
            ViewBag.OriginalUrl = originalUrl;
            EnsureItems(keywords, SearchProviderManager.GetSearchProvider("Google"));
            return View();
        }

        public ActionResult GSHResult()
        {
            var keywords = Request.QueryString["q"] ?? string.Empty;
            var originalUrl = Request.QueryString["originalurl"] ?? string.Empty;
            var provider = Request.QueryString["provider"] ?? "GoogleCSE";

            var searchProvider = SearchProviderManager.GetSearchProvider("SelfGoogle");
            EnsureItems(keywords, searchProvider);
            ViewBag.OriginalUrl = originalUrl;
            ViewBag.SearchProvider = provider;
            ViewBag.Keywords = keywords;
            return View();
        }

        public ActionResult YResult()
        {
            var originalUrl = Request.QueryString["originalurl"] ?? string.Empty;
            var keywords = Request.QueryString["q"] ?? string.Empty;

            ViewBag.SearchProvider = "Y";
            EnsureItems(keywords, SearchProviderManager.GetSearchProvider("Yahoo"));
            ViewBag.OriginalUrl = originalUrl;
            return View();
        }

        public ActionResult ShowFeed(string provider)
        {
            var searchProvider = SearchProviderManager.PlayDice();
            EnsureItems(string.Empty, searchProvider);
            ViewBag.Provider = provider;
            ViewBag.Keywords = string.Empty;
            return View();
        }

        public ActionResult GetFeed(int pageIndex, int pageSize, string provider, string keywords)
        {
            var crawler = new StoryCrawler();
            var result = crawler.GetSearchResults(keywords, new string[] { provider }, pageIndex);

            var finalResult = result;

            if (!provider.Equals("GoogleCSE", StringComparison.InvariantCultureIgnoreCase)
                && !provider.Equals("Ebay", StringComparison.InvariantCultureIgnoreCase)
                //&& !provider.Equals("Twitter", StringComparison.InvariantCultureIgnoreCase)
                && !provider.Equals("YouTube", StringComparison.InvariantCultureIgnoreCase))
                finalResult = result.Skip(pageSize * pageIndex).Take(pageSize).ToList();

            var jsonData = new
            {
                nextPage = pageIndex + 1,
                canFetch = finalResult.Count == pageSize,
                crawlers = finalResult.Select(x => new { x.Title, x.Description, x.DisplayUrl, x.ClickUrl, x.UpdateDate })
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }

        public ActionResult GetDefaultResult(string keywords)
        {
            if (string.IsNullOrEmpty(keywords))
                keywords = AppGlobal.DefaultKeywords;

            var searchProvider = SearchProviderManager.PlayDice();

            EnsureItems(keywords, searchProvider);

            ViewBag.TopKeywords = GetTopKeywords(searchProvider);
            ViewBag.TopTags = GetTopTags(searchProvider);

            return PartialView("Index");
        }

        public ActionResult GetTopKeywords(string keywords)
        {
            var searchProvider = SearchProviderManager.PlayDice();
            var topKeywords = GetTopKeywords(searchProvider);

            var jsonData = new
            {
                topKeywords = topKeywords.Select(x => new { x.Title, x.ClickUrl })
            };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Error()
        {
            var searchProvider = SearchProviderManager.PlayDice();

            ViewBag.TopKeywords = GetTopKeywords(searchProvider);
            ViewBag.TopTags = GetTopTags(searchProvider);
            EnsureItems(AppGlobal.DefaultKeywords, searchProvider);

            return View();
        }

        #endregion

        #region Private

        private void EnsureItems(string keywords, ISearchProvider searchProvider)
        {
            var relatedKeywords = GetRelatedKeywords(keywords, searchProvider);
            ViewBag.RelatedKeywords = relatedKeywords;

            var metaTags = GetMetaTags(keywords);
            ViewBag.MetaTags = metaTags;

            ViewBag.Keywords = keywords;
        }

        private IList<FeedViewModel> GetRelatedKeywords(string keywords, ISearchProvider searchProvider)
        {
            var keywordList = _keywordService.GetTopKeywords(_relatedKeywordsLimit);
            var topKeywords = keywordList.Select(x =>
            {
                return new FeedViewModel()
                {
                    Title = x.Word,
                    ClickUrl = searchProvider.BuildNavigateUrl(x.Word)
                };
            }).ToList();

            return topKeywords;
        }

        private string GetMetaTags(string keywords)
        {
            var keywordList = _keywordService.GetTopKeywords(20);
            var keywordsValue = keywordList.Select(x => x.Word);
            var metaTags = string.Join(",", keywords);

            return metaTags;
        }

        private IList<FeedViewModel> GetTopKeywords(ISearchProvider searchProvider)
        {
            var keywords = _keywordService.GetTopKeywords(15);
            var topKeywords = keywords.Select(x =>
            {
                return new FeedViewModel()
                {
                    Title = x.Word,
                    ClickUrl = searchProvider.BuildNavigateUrl(x.Word)
                };
            }).ToList();

            return topKeywords;
        }

        private IList<TagViewModel> GetTopTags(ISearchProvider searchProvider)
        {
            var tags = _keywordService.GetTopTags(4);
            var topTags = tags.Select(t =>
            {
                return new TagViewModel()
                {
                    Name = t.Name,
                    Keywords = t.KeywordList.Select(k =>
                    {
                        return new FeedViewModel()
                        {
                            Title = k.Word,
                            ClickUrl = searchProvider.BuildNavigateUrl(k.Word)
                        };
                    }).ToList()
                };
            }).ToList();

            return topTags;
        }

        #endregion
    }
}
